package ru.jexp.rcp.supply.n.form;

import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.nebula.widgets.formattedtext.FormattedText;
import org.eclipse.nebula.widgets.formattedtext.FormattedTextObservableValue;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.FormToolkit;

import ru.jexp.rcp.supply.swtext.DecimalFormatter;
import ru.jexp.rcp.supply.swtext.ILookup;
import ru.jexp.rcp.supply.swtext.JExpConverter;
import ru.jexp.rcp.supply.swtext.LookupField;
import ru.jexp.rcp.supply.swtext.LookupFieldView;
import ru.jexp.rcp.supply.swtext.factory.JExpLayoutFactory;

public class FieldFactory
{
	private FormToolkit toolkit;

	public FieldFactory(FormToolkit toolkit)
	{
		this.toolkit = toolkit;
	}

	public FormToolkit getToolkit()
	{
		return toolkit;
	}

	public IJExpObservable<Text> createText(Composite parent)
	{
		Text text = toolkit.createText(parent, null, SWT.BORDER);
		return new JExpObservable<Text>(text, SWTObservables.observeText(text, SWT.Modify));
	}

	public IJExpObservable<Text> createText(Composite parent, String label)
	{
		toolkit.createLabel(parent, label);
		return createText(parent);
	}

	public IJExpObservable<Spinner> createSpinner(Composite parent, String label, int startValue)
	{
		toolkit.createLabel(parent, label);
		Spinner spinner = new Spinner(parent, SWT.BORDER);
		spinner.setMinimum(startValue);
		return new JExpObservable<Spinner>(spinner, SWTObservables.observeSelection(spinner));
	}

	public IJExpObservable<FormattedText> createDecimal(Composite parent)
	{
		FormattedText formattedText = new FormattedText(toolkit.createText(parent, null, SWT.BORDER));
		formattedText.setFormatter(new DecimalFormatter(DecimalFormatter.EDIT_MASK_2));
		return new JExpObservable<FormattedText>(formattedText, new FormattedTextObservableValue(formattedText));
	}

	public IJExpObservable<FormattedText> createDecimal(Composite parent, String label)
	{
		toolkit.createLabel(parent, label);
		return createDecimal(parent);
	}

	public IJExpObservableList<Combo> createEdizmerCombo(Composite parent)
	{
		Combo combo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
		combo.setLayoutData(JExpLayoutFactory.gdWithSizeHorizontal(30));
		return new JExpObservableList<Combo>(combo, SWTObservables.observeSingleSelectionIndex(combo), SWTObservables.observeItems(combo));
	}

	public <ReturnedT, LookupT extends ILookup<ReturnedT>> IJExpObservableLookup createLookup(Composite parent, String label, LookupT lookup, Class<ReturnedT> type)
	{
		return createLookup(parent, label, lookup, type, null);
	}

	public <ReturnedT, LookupT extends ILookup<ReturnedT>> IJExpObservableLookup createLookup(Composite parent, String label, LookupT lookup, Class<ReturnedT> type, JExpConverter converter)
	{
		LookupFieldView fieldView = LookupFieldView.createWithHyperLink(toolkit, parent, label);
		LookupField<ReturnedT, LookupT> field = new LookupField<ReturnedT, LookupT>(fieldView, lookup, type);
		if (converter != null)
		{
			field.setConverter(converter);
		}
		return new JExpObservableLookup(fieldView, field.observe());
	}

	public IJExpObservable<Button> createCheckButton(Composite parent, String label)
	{
		toolkit.createLabel(parent, label);
		Button button = toolkit.createButton(parent, "", SWT.CHECK);
		return new JExpObservable<Button>(button, SWTObservables.observeSelection(button));

	}
}
